<template>
  <div class="site-action">
    <el-scrollbar>
      <el-timeline
        v-infinite-scroll="load"
        :infinite-scroll-disabled="disableLoad"
      >
        <transition-group
          tag="div"
          name="fade-transform"
          leave-active-class="fade-transform-leave-active position-absolute"
        >
          <el-timeline-item
            v-for="action in filterActionList"
            :key="action.id"
            :timestamp="$dayjs(action.created).fromNow()"
            placement="top"
            size="large"
            :icon="action.verb | getVerbInfo('icon')"
            :color="action.verb | getVerbInfo('color')"
          >
            <el-card class="el-timeline-body">
              <span style="color: #7f8c8d">#{{ action.id }}</span>
              <p class="el-timeline-body__title">
                <el-tag
                  effect="plain"
                  :type="action.verb | getVerbInfo('type')"
                  style="font-size: 16px"
                >
                  {{ action.verb | getVerbInfo("text") }}
                </el-tag>
                <span v-if="action.target">
                  <strong style="margin-left: 10px"
                    >{{ action.target_ct }} </strong
                  >:
                  <i>{{ action.target ? action.target.name : action.info }}</i>
                </span>
                <span v-if="action.info">
                  <strong style="margin-left: 10px">{{
                    action.info
                  }}</strong></span
                >
              </p>
              <p style="display: flex; align-items: center">
                <el-avatar :src="action.user.avatar">
                  <i class="el-icon-user-solid" />
                </el-avatar>
                <span style="margin-left: 10px">
                  <strong
                    >{{ action.user.username }}
                    <span v-if="action.user.nickname"
                      >({{ action.user.nickname }})</span
                    ></strong
                  >
                  <i style="font-size: 14px">&nbsp;&nbsp;于&nbsp;&nbsp;</i>
                  <span>{{
                    $dayjs(action.created).format("YYYY-MM-DD HH:mm:ss")
                  }}</span>
                </span>
              </p>
            </el-card>
          </el-timeline-item>
        </transition-group>
      </el-timeline>
    </el-scrollbar>
    <div style="padding-right: 20px; width: 30%">
      <site-action-filter v-bind.sync="filter" />
    </div>
  </div>
</template>

<script>
import SiteActionFilter from "./SiteActionFilter";

export const actionMap = {
  get: {
    text: "访问",
    type: "success",
    icon: "el-icon-view",
    color: "#67C23A",
  },
  login: {
    text: "登录",
    type: "success",
    icon: "el-icon-d-arrow-right",
    color: "#67C23A",
  },
  logout: {
    text: "登出",
    type: "info",
    icon: "el-icon-d-arrow-left",
    color: "#D3D4D6",
  },
  create: {
    text: "创建",
    type: "success",
    icon: "el-icon-plus",
    color: "#67C23A",
  },
  delete: {
    text: "删除",
    type: "danger",
    icon: "el-icon-delete",
    color: "#F56C6C",
  },
  update: {
    text: "更新",
    type: "warning",
    icon: "el-icon-edit",
    color: "#E6A23C",
  },
};
export default {
  name: "SiteAction",
  components: {
    SiteActionFilter,
  },
  data() {
    return {
      page: 1,
      size: 20,
      count: 0,
      actionList: [],
      disableLoad: false,
      timer: null,
      pollingRun: false,
      filter: {
        // 做数据筛选的对象
        keyword: "",
        timeRange: [],
        actionSelected: [],
      },
    };
  },
  methods: {
    async getActions() {
      const { count, results } = await this.$api.getActions({
        size: this.size,
      });
      this.count = count;
      this.actionList = results;
      //   console.log(this.actionList);
    },
    async load() {
      //节流阀 来控制 无限加载的请求频率
      this.disableLoad = true;

      this.page++;
      this.size = this.page * 20;
      //   console.log(this.page, this.size);
      await this.getActions();

      // 上一次请求结束之后，我们再开启节流阀 允许下一次的请求
      setTimeout(() => {
        this.disableLoad = false;
      }, 500);
    },

    // 轮询服务器方法
    polling() {
      this.pollingRun = true;
      clearTimeout(this.timer);
      this.timer = setTimeout(async () => {
        await this.getActions();
        if (this.pollingRun) this.polling(); // 轮询递归
      }, 5000);
    },

    startPolling() {
      if (this.pollingRun) return;
      this.polling();
    },
    endPolling() {
      this.pollingRun = false;
      clearTimeout(this.timer);
      this.timer = null;
    },
  },
  filters: {
    getVerbInfo(verb, key) {
      return actionMap[verb][key];
    },
  },
  computed: {
    filterActionList() {
      let arr = [...this.actionList];

      if (this.filter.keyword) {
        const keyword = this.filter.keyword.toLowerCase();
        arr = arr.filter(
          (item) =>
            item.user.username.toLowerCase().includes(keyword) ||
            item.user.nickname.toLowerCase().includes(keyword)
        );
      }

      if (this.filter.timeRange && this.filter.timeRange.length > 0) {
        let [start, end] = this.filter.timeRange;
        end = end || new Date();
        arr = arr.filter(
          (item) =>
            new Date(item.created) >= start && new Date(item.created) <= end
        );
      }

      if (this.filter.actionSelected) {
        arr = arr.filter((item) =>
          this.filter.actionSelected.includes(item.verb)
        );
      }

      return arr;
    },
  },
  watch: {
    ["filterActionList.length"](val) {
      if (val < 20) {
        this.load();
      }
    },
  },
  created() {
    this.getActions();
    this.startPolling();
    this.filter.actionSelected = Object.keys(actionMap);
  },
  beforeDestory() {
    this.endPolling();
  },
  activated() {
    this.getActions();
    this.startPolling();
  },
  deactivated() {
    this.endPolling();
  },
};
</script>

<style lang="scss" scoped>
// .box {
//   height: 400px;
//   overflow: auto;
.site-action {
  display: flex;
}

.el-scrollbar {
  width: 70%;
  height: calc(100vh - 136px);
  ::v-deep.el-scrollbar__wrap {
    width: calc(100% + 30px) !important;
    height: 103%;
    padding-right: 30px;
  }
}

.el-timeline-item {
  ::v-deep.el-timeline-item__node {
    width: 16px;
    height: 16px;
    left: -3px;
  }
}
</style>
